package corestruct

import (
	"container/list"
	"sync"
)

type Queue struct {
	list   *list.List
	locker sync.Mutex
}

func (p *Queue) Push(elem interface{}) {
	p.locker.Lock()
	defer func() {
		p.locker.Unlock()
	}()
	if p.list == nil {
		p.list = list.New()
	}
	p.list.PushBack(elem)

}
func (p *Queue) Pop() interface{} {
	p.locker.Lock()
	defer p.locker.Unlock()
	if p.list == nil {
		p.list = list.New()
	}

	if elem := p.list.Front(); elem != nil {
		p.list.Remove(elem)
		return elem.Value
	}
	return nil
}
func (p *Queue) PushList(l []interface{}) {
	p.locker.Lock()
	defer p.locker.Unlock()
	if p.list == nil {
		p.list = list.New()
	}

	for _, v := range l {
		p.list.PushBack(v)
	}
}
func (p *Queue) PopAll() []interface{} {
	var r = make([]interface{}, 0)
	p.locker.Lock()
	defer p.locker.Unlock()
	if p.list == nil {
		p.list = list.New()
	}
	for {
		if elem := p.list.Front(); elem != nil {
			p.list.Remove(elem)
			r = append(r, elem.Value)
		} else {
			break
		}
	}

	return r
}

func (p *Queue) Count() int {
	p.locker.Lock()
	defer p.locker.Unlock()
	if p.list == nil {
		p.list = list.New()
	}
	return p.list.Len()
}
